package com.haiheng.common.socket.websocket;

import android.text.TextUtils;
import android.util.Log;

import com.haiheng.common.api.API;
import com.haiheng.library.log.LogUtils;
import com.haiheng.library.log.LogWriter;
import com.haiheng.library_base.model.ApplicationViewModel;
import com.haiheng.library_base.msg.MsgCode;
import com.haiheng.library_base.msg.MsgEvent;
import com.haiheng.library_base.utils.DateUtils;
import com.haiheng.library_base.utils.GsonUtil;
import com.haiheng.library_base.utils.rxutils.RxHeartTimerUtil;
import com.haiheng.library_base.utils.rxutils.RxReceiveWorkTimerUtil;

import org.json.JSONObject;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

// An highlighted block
public final class WebSocketManager {

    private static final String TAG = "WebSocketManager";
    private static WebSocketManager mInstance = null;

    private OkHttpClient client;
    private Request request;
    private WebSocket mWebSocket;

    private volatile boolean isConnect = false;

    // 每隔15秒 发送一次心跳包，检测连接没有断开
    private static final long HEART_BEAT_RATE = 15 * 1000;

    // 发送心跳后10S之后检测服务器返回的心跳
    private static final long HEART_CHECK = 10 * 1000;

//    private String WSURL = ApiResult.get;


    private WebSocketManager() {
    }

    public static WebSocketManager getInstance() {
        if (null == mInstance) {
            synchronized (WebSocketManager.class) {
                if (mInstance == null) {
                    mInstance = new WebSocketManager();
                }
            }
        }
        return mInstance;
    }

    /**
     * 释放单例, 及其所引用的资源
     */
    public void release() {
        try {
            if (mInstance != null) {
                mInstance = null;
            }
        } catch (Exception e) {
            Log.e("WebSocketManager", "release : " + e.toString());
        }
    }

    public void init() {
//        String socketUrl = API.Companion.getSocketUrl();
        String socketUrl = "ws://192.168.0.123:8222";
        LogUtils.e("初始化websocket........."+socketUrl);
        client = new OkHttpClient.Builder()
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)
                .build();
        request = new Request.Builder().url(socketUrl).build();
        /**
         * 连接
         */
        connect();

    }

    /**
     * 连接
     * 每次进来都要判断是否已经连接成功
     */
    synchronized public void connect() {
        if (isConnect) {
            //发消息出去，让进度条关闭
            MsgEvent event = new MsgEvent();
            event.setCode(MsgCode.RE_CONNECT_SUCCESS);
            ApplicationViewModel.Companion.get().getEven().postValue(event);
        } else {
            client.newWebSocket(request, createListener());
        }


    }

    /**
     * 加锁重连
     * 每次进来都要判断是否已经连接成功
     */
    synchronized public void reconnect() {
        try {
            Thread.sleep(2000);
            if (isConnect) {
                //发消息出去，让进度条关闭
                MsgEvent msgEvent = new MsgEvent();
                msgEvent.setCode(MsgCode.RE_CONNECT_SUCCESS);
                ApplicationViewModel.Companion.get().getEven().postValue(msgEvent);
            } else {
                LogWriter.e("websocket正在重新连接中");
                //发消息出去
                MsgEvent event = new MsgEvent();
                event.setCode(MsgCode.RE_CONNECT);
                ApplicationViewModel.Companion.get().getEven().postValue(event);
                connect();
            }
        } catch (Exception e) {
            LogWriter.e("websocket重新连接异常：" + e.getMessage());
            e.printStackTrace();
        }

    }


    /**
     * 关闭连接
     */
    public void close() {
        if (mWebSocket != null) {
            mWebSocket.cancel();
            mWebSocket.close(1001, "客户端主动关闭连接");

        }


    }


    /**
     * 发送消息
     *
     * @param text 字符串
     * @return boolean
     */
    public boolean sendMessage(String text) {

        return mWebSocket.send(text);
    }

    private WebSocketListener createListener() {
        return new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                super.onOpen(webSocket, response);
                LogUtils.e(TAG+"onOpen: onMessage");
                mWebSocket = webSocket;
                isConnect = response.code() == 101;
                if (!isConnect) {
                    reconnect();
                } else {
                    LogWriter.e("WebSocket 连接成功");
                    //发消息出去，让进度条关闭
                    MsgEvent event = new MsgEvent();
                    event.setCode(MsgCode.RE_CONNECT_SUCCESS);
                    //EventBus.getDefault().post(event);
                    ApplicationViewModel.Companion.get().getEven().postValue(event);
                    /**
                     * 初始化小车
                     */
                    initSmartCart();
                    /**
                     * 初始化心跳
                     */
                    initHeartTimeTask();

                }
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {
                super.onMessage(webSocket, text);
                getMessage(text);


            }

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                super.onMessage(webSocket, bytes);
                LogUtils.e(TAG+"onMessage: ");
                String text = bytes.base64();
                getMessage(text);
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                super.onClosing(webSocket, code, reason);
                LogUtils.e(TAG+"onClosing: ");
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                super.onClosed(webSocket, code, reason);
                LogUtils.e(TAG+"onClosed: ");
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                super.onFailure(webSocket, t, response);
                LogUtils.e(TAG+"onFailure: " + t.getMessage());
                if ("Network is unreachable".equals(t.getMessage())) {
                    //发消息出去
                    MsgEvent event = new MsgEvent();
                    event.setCode(MsgCode.RE_CONNECT);
                    //  EventBus.getDefault().post(event);
                    ApplicationViewModel.Companion.get().getEven().postValue(event);
                    isConnect = false;
                    reconnect();
                }

                if (t.getMessage().contains("Failed to connect to")) {
                    //发消息出去
                    MsgEvent event = new MsgEvent();
                    event.setCode(MsgCode.RE_CONNECT);
                    //  EventBus.getDefault().post(event);
                    ApplicationViewModel.Companion.get().getEven().postValue(event);
                    isConnect = false;
                    reconnect();
                }


            }
        };
    }

    /**
     * websocket收到服务端的消息
     *
     * @param message
     */
    private void getMessage(String message) {
        LogWriter.e("websocket收到的消息: " + message);
        if (TextUtils.isEmpty(message)) {
            return;
        }
        /**
         * 收到心跳
         */
        if (message.contains("心跳")) {
            receriveHeart = message;
            return;
        }
        /**
         * 收到初始化成功
         */
        if (message.contains("IsSucceed")) {
            return;
        }
        try {
            //解析收到的消息
//            WebSocketMsg msg = JSONObject.parseObject(message, WebSocketMsg.class);
//            MsgEvent event = new MsgEvent();
//
//            ApplicationViewModel.Companion.get().getEven().postValue(event);

        } catch (Exception e) {
            LogWriter.e("websokcet数据解析异常" + e.getMessage());
        }
    }

    /**
     * 连接成功，初始化小车，向服务器发送初始化的消息
     */
    private void initSmartCart() {
        //初始化小车
        WebSocketMsg vo = new WebSocketMsg();
        vo.setPassword("123456");
        vo.setPatronSn("123456");
        //初始化小车
        sendMessage(GsonUtil.getString(vo));
    }

    /**
     * 初始化心跳
     */
    private void initHeartTimeTask() {
        RxHeartTimerUtil.cancel();
        RxHeartTimerUtil.interval(HEART_BEAT_RATE, new RxHeartTimerUtil.IRxNext() {
            @Override
            public void doNext() {
                //发送心跳消息
                senHeartMsg();
            }
        });


    }

    /**
     * 接受到的心跳
     */
    private volatile String receriveHeart;

    /**
     * 发送心跳消息
     */
    private void senHeartMsg() {
        RxReceiveWorkTimerUtil.cancel();
        receriveHeart = null;
        WebSocketMsg msg = new WebSocketMsg();
        msg.setPatronSn("Heartbeat");
        msg.setPatronName("123456");
        LogWriter.e("发送心跳: 内容 - " + GsonUtil.getString(msg) + "  时间 - " + DateUtils.dateToString("yyyy-MM-dd HH:mm:s", new Date()));
        boolean isSend = sendMessage(GsonUtil.getString(msg));
        // LogUtils.e("心跳是否发送成功" + isSend);
        RxReceiveWorkTimerUtil.timer(HEART_CHECK, new RxReceiveWorkTimerUtil.IRxNext() {
            @Override
            public void doNext() {
                if (receriveHeart == null) {
                    isConnect = false;
                    reconnect();
                }
                else{
                    isConnect = true;
                }
            }
        });


    }

}